<?php

/**
 * JingYao-backend
 *
 * @link     https://gitee.com/wang-zhihui-release/jingyao-backend
 * @apiDocument https://gitee.com/wang-zhihui-release/jingyao-backend/wikis/
 */

namespace App\Services;

use App\Enums\AdminActionTypeEnum;
use App\Enums\IdentityVisibilityEnum;
use App\Enums\UserIdentityEnum;
use App\Exceptions\ApiException;
use App\Format\BannerFormat;
use App\Models\Banner;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Log;

class BannerService
{
    public function getBanners()
    {
        $builder = Banner::query()->where('is_hide', 'N');
        $builder = $this->builderIdentityVisibility($builder);
        return $builder->get()->toArray();
    }

    public function getAdminBanners(int $page, int $pageSize, array $search)
    {
        $builder = Banner::query();

        if (isset($search['start_date'], $search['end_date'])) {
            $builder->where('push_time', '>=', strtotime($search['start_date']));
            if (strlen($search['end_date']) > 10) {
                $builder->where('push_time', '<=', strtotime($search['end_date']));
            } else {
                $builder->where('push_time', '<=', strtotime($search['end_date']) + (24 * 3600));
            }
        }
        if (isset($search['start_date']) && ! isset($search['end_date'])) {
            $builder->where('push_time', '>=', strtotime($search['start_date']));
        }
        if (! isset($search['start_date']) && isset($search['end_date'])) {
            if (strlen($search['end_date']) > 10) {
                $builder->where('push_time', '<=', strtotime($search['end_date']));
            } else {
                $builder->where('push_time', '<=', strtotime($search['end_date']) + (24 * 3600));
            }
        }

        if (isset($search['identity_visibility'])) {
            $builder->where('identity_visibility', $search['identity_visibility']);
        }

        if (isset($search['title'])) {
            $builder->where('title', $search['title']);
        }

        $count = $builder->count();

        $list = $builder->skip(($page - 1) * $pageSize)->take($pageSize)->get();
        if (! empty($search)) {
            adminLog(new Banner(), AdminActionTypeEnum::SELECT, '查询 banner 列表');
        }
        return [
            'count' => $count,
            'page' => $page,
            'page_size' => $pageSize,
            'list' => $list,
        ];
    }

    public function create(BannerFormat $bannerFormat)
    {
        if (empty($bannerFormat->getIsHide())) {
            $bannerFormat->setIsHide('N');
        }
        if ($bannerFormat->getIsHide() == 'N') {
            $this->checkShowBannerCount($bannerFormat->getIdentityVisibility());
        }
        $bannerFormat->setPushTime(time());
        $banner = Banner::query()->create($bannerFormat->toArrayNotNull());
        adminLog($banner, AdminActionTypeEnum::CREATE, '创建 banenr');
        return true;
    }

    public function update(BannerFormat $bannerFormat)
    {
        if (empty($bannerFormat->getId())) {
            throw new ApiException('缺少 id', 1);
        }
        if ($bannerFormat->getIsHide() == 'N') {
            $this->checkShowBannerCount($bannerFormat->getIdentityVisibility());
        }
        $banner = Banner::query()->find($bannerFormat->getId());
        $data = $bannerFormat->toArrayNotNull();
        unset($data['id']);
        $banner->update($data);
        adminLog($banner, AdminActionTypeEnum::UPDATE, '修改 banner');
        return true;
    }

    public function delete(int $id)
    {
        /** @var null|Banner $banner */
        $banner = Banner::query()->find($id);
        if (empty($banner)) {
            throw new ApiException('banner 不存在', 1);
        }
        adminLog($banner, AdminActionTypeEnum::DELETE, '删除 banner');
        $banner->delete();
        return true;
    }

    private function builderIdentityVisibility(Builder $builder)
    {
        $userId = request()->input('user_id', null);
        if (empty($userId)) {
            $builder->where('identity_visibility', IdentityVisibilityEnum::ALL);
            return $builder;
        }
        /** @var null|User $user */
        $user = User::query()->select('identity')->find($userId);
        if (empty($user)) {
            Log::error(sprintf('用户 【%s】 不存在', $userId));
            return $builder;
        }
        if ($user->identity == UserIdentityEnum::FLOW_USER) {
            $builder->whereIn('identity_visibility', [IdentityVisibilityEnum::FLOW_USER, IdentityVisibilityEnum::ALL]);
            return $builder;
        }

        $builder->whereIn('identity_visibility', [IdentityVisibilityEnum::ALL, IdentityVisibilityEnum::NOT_FLOW]);
        return $builder;
    }

    private function checkShowBannerCount(int $identityVisibility)
    {
        if ($identityVisibility == IdentityVisibilityEnum::ALL) {
            $count = Banner::query()->where('is_hide', 'N')
                ->where('identity_visibility', $identityVisibility)
                ->count();
        } else {
            $count = Banner::query()->where('is_hide', 'N')
                ->whereIn('identity_visibility', [IdentityVisibilityEnum::ALL, $identityVisibility])
                ->count();
        }
        if ($count >= 5) {
            throw new ApiException('无法新设置展示更多', 1);
        }
        return true;
    }
}
